<?php

class LightJob_Backend_MySQL implements LightJob_IBackend
{
	private $conf;
	
	/**
	 * PDO handler
	 *
	 * @var PDO
	 */
	private $dbh;
	
	public function __construct()
	{
		$this->conf = array();
		$this->dbh = null;
	}
	public function configure($conf)
	{
		$this->conf = $conf;
	}

	public function connect()
	{
		if($this->dbh!==null)
		{
			throw new BackendException("Connection already established to MySQL backend",601);
		}
		$host = $this->conf['database.params.host'];
		$username = $this->conf['database.params.username'];
		$password = $this->conf['database.params.password'];
		$dbname = $this->conf['database.params.dbname'];
		
		try
		{	
			$this->dbh = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
		}
		catch(PDOException $e)
		{
			throw new BackendException("Unable to connect to MySQL backend: ".$e->getMessage());
		}
		
		return true;
	}
	
	protected function checkConnected()
	{
		if($this->dbh===null) throw new BackendException("No connection available");
	}
	
	public function clearAllJobs()
	{
		$this->checkConnected();
		try
		{
			$this->dbh->query('DELETE FROM jobs;');
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when deleteing jobs: ".$e->getMessage(),602);
		}
		
		return true;
	}

	public function hasPendingJobs()
	{
		return $this->countPendingJobs()>0;
	}

	public function countPendingJobs()
	{
		$this->checkConnected();
		try
		{
			$count = $this->dbh->query('SELECT count(id) as nb FROM jobs WHERE executed IS NULL AND waiting <= \''.date('Y-m-d H:i:s',time()).'\' ;');
			$count = $count->fetchAll();
			return $count[0]['nb'];
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when counting jobs: ".$e->getMessage(),603);
		}
	}
	
	public function listPendingJobs()
	{
		$this->checkConnected();
		try
		{
			$rows = $this->dbh->query('SELECT id,mode,action,params,extraparams,created,waiting FROM jobs WHERE executed IS NULL AND waiting <= \''.date('Y-m-d H:i:s',time()).'\' ORDER BY waiting ASC;');
			return $rows->fetchAll();
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when selecting jobs: ".$e->getMessage(),603);
		}
	}
	
	public function addJob($job)
	{
		$this->checkConnected();
		try
		{
			$this->dbh->query("INSERT INTO jobs (action,mode,params,extraparams,created,waiting) VALUES ('{$job['action']}','{$job['mode']}','{$job['params']}','{$job['extraparams']}','".date('Y-m-d H:i:s',time())."','".$job['waiting']."');");
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when adding a new job: ".$e->getMessage());
		}
		
		return true;
	}
	
	public function markJobCompleted($job)
	{
		return $this->markJobsCompleted(array($job));
	}
	
	public function markJobsCompleted($jobs)
	{
		$this->checkConnected();
		try
		{
			$ids = '';
			foreach($jobs as $j){
				if(is_array($j) && array_key_exists('id',$j)){
					$ids.=($ids ? "," : "").$j['id'];
				}
			}
			$this->dbh->query("UPDATE jobs SET executed = '".date('Y-m-d H:i:s',time())."' WHERE id IN (".$ids.");");
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when trying to mark job as executed: ".$e->getMessage());
		}
		return true;
	}
	
	public function cleanJobs()
	{
		$this->checkConnected();
		try
		{
			$this->dbh->query("DELETE FROM jobs WHERE NOT(executed IS NULL);");
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when cleaning jobs: ".$e->getMessage());
		}
		
		return true;
	}
	
	public function listJobs()
	{
		$this->checkConnected();
		try
		{
			$rows = $this->dbh->query('SELECT id,mode,action,params,extraparams,created,waiting FROM jobs ORDER BY waiting ASC;');
			return $rows->fetchAll();
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when selecting jobs: ".$e->getMessage(),603);
		}
	}
		
	public function countJobs()
	{
		$this->checkConnected();
		try
		{
			$count = $this->dbh->query('SELECT count(id) as nb FROM jobs;');
			$count = $count->fetchAll();
			return $count[0]['nb'];
		}
		catch(PDOException $e)
		{
			throw new BackendException("Error when counting jobs: ".$e->getMessage(),603);
		}
	}
	
	public function __destruct()
	{
		$this->dbh = null;
	}
	
}
